Trend Micro Deep SecurityのSDKにSOAP APIを追加実装してみた
はじめに
こんにちは、藤本です。
先日、Deep Security API、SDK(deep-security-py)を紹介する記事をエントリしました。
今回はdeep-security-pyに実装されていないSOAP APIを追加実装する方法をご紹介します。
概要
deep-security-pyは現在、Deep Securityが持つAPIの60%ぐらいを実装しています。残りの40%は実装されていません。ただSDKはSOAP APIをコールするための多くの処理を抽象化して実装しているため、APIの追加実装は難しくありません。今回はdeep-security-pyに実装されていないAPIの実装方法を順を追って説明します。
deep-security-pyの処理の流れ
実装する前にdeep-security-pyがSOAP APIをコールする処理の流れを理解する必要があります。deep-security-pyの処理の流れを先日のブログで紹介したポリシー作成を例にザックリ説明します。
class Policy(core.CoreObject): # (a) : def save(self): """ Save any changes made to the policy """ result = False soap_call = self.manager._get_request_format(call='securityProfileSave') # (b) soap_call['data'] = { 'sp': self.to_dict() } # (c) if soap_call['data']['sp'].has_key('manager'): # (d) del(soap_call['data']['sp']['manager']) response = self.manager._request(soap_call) # (e) if response['status'] == 200: result = True else: result = False if 'log' in dir(self): self.log("Could not save the policy. Returned: {}".format(response), level='error') return result
(a) Policyクラス
SOAP APIのリクエストのXMLを作成する、レスポンスのXMLを受け取るクラスです。dict形式で設定値を持ちます。
(b) APIの指定
引数call
に呼び出すSOAP APIのAPI名を指定します。
API名はSOAP APIのドキュメントのWeb Methodsの章から探してください。
ポリシー作成の場合、API名はsecurityProfileSave
です。
(c) パラメータ取得
Policyインスタンスが持つプロパティをSOAP APIのパラメータとして取得します。前回の例だと必要最低限のname
のみ設定したため、ここではname
とインスタンス初期化時に設定したmanager
を取得します。
APIに対して必要なパラメータはSOAP APIのドキュメントをご参照ください。
securityProfileSave
の場合、パラメータはSecurityProfileTransport
です。
(d) 不要パラメータの削除
SecurityProfileTransport
はmanager
をプロパティに持たないため、不要なものとして削除します。
(e) リクエスト
以上の設定だけすれば、あとはリクエスト発行の共通処理が全て実施してくれます。共通処理が実施する処理をザックリ書くと以下のようになります。
- パラメータにセッションID追加
- パラメータからSOAPエンベロープ生成
- HTTPリクエストのヘッダ、メソッド設定
- urllib2によるHTTPリクエスト
- レスポンスのXMLをdictに変換
ポリシー削除を実装する
ポリシーを作成、取得、変更するAPIはSDKに実装されていますが、削除のAPIは実装されていません。
今回はポリシー削除をdeep-security-pyに追加実装します。
ドキュメントを読み解く
SOAP APIのドキュメントからSOAP API発行に必要な情報を取得します。上で説明した通り、SOAP APIを発行するためにはAPI名、APIに対するパラメータが必要となります。
API名はドキュメントのDescriptionからsecurityProfileDelete
になります。
パラメータはids
(削除対象ポリシーのID)、sID
(ログイン時に発行されるセッションID)となります。なお、sID
は共通処理のセッションID追加により設定されるため、実装する上で意識する必要はありません。
実装する
Policyクラスにdelete
メソッドとしてポリシー削除処理を実装します。
class Policy(core.CoreObject): : def delete(self): result = False soap_call = self.manager._get_request_format(call='securityProfileDelete') # (a) soap_call['data'] = { 'ids': self.id } # (b) response = self.manager._request(soap_call) # (c) if response['status'] == 200: result = True else: result = False if 'log' in dir(self): self.log("Could not delete the policy. Returned: {}".format(response), level='error') return result
(a) API名指定
引数call
に上で調べたsecurityProfileDelete
を指定します。
(b) パラメータ指定
パラメータのids
にポリシーIDをセットします。
(c) リクエスト
あとはリクエスト発行の共通処理をコールします。
動作確認
対話式で確認します。
まずはログインします。
# python Python 2.7.11 (default, Mar 17 2016, 18:31:58) [GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> TENANT = XXXXXXXXXXX >>> USERNAME = 'apiuser' >>> PASSWORD = XXXXXXXXXXXXX >>> import deepsecurity >>> mgr = deepsecurity.dsm.Manager(tenant=TENANT, username=USERNAME, password=PASSWORD) >>> mgr.sign_in() True
続いて、ポリシー一覧、削除対象ポリシーを取得します。
今回削除するポリシーはDelete Policyです。
>>> mgr.policies[241].name u'Delete Policy' >>> policy = mgr.policies[241]
実装したdelete
メソッドを呼び出します。
>>> policy.delete() True
再度ポリシー一覧を取得し、削除したポリシーがないことを確認します。
>>> mgr = deepsecurity.dsm.Manager(tenant=TENANT, username=USERNAME, password=PASSWORD) >>> mgr.sign_in() True >>> mgr.policies.get() >>> mgr.policies[241] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 241 >>> filter(lambda policy: policy.name == 'Delete Policy', mgr.policies.values()) []
IDでも、名前でも検索できないので、無事削除されました。
Webコンソール上でも削除されています。
まとめ
いかがでしたでしょうか?
deep-security-pyはコード量も少なく、多くの処理が共通化されているため、追加実装が難しくありません。是非、みなさんもより多くのAPIに対応できるように実装してみましょう。